package com.sxhuayuan.parking.service.impl;

import com.sxhuayuan.parking.compenent.Filter;
import com.sxhuayuan.parking.compenent.Page;
import com.sxhuayuan.parking.compenent.Pageable;
import com.sxhuayuan.parking.dao.BaseDao;
import com.sxhuayuan.parking.dao.OrderDao;
import com.sxhuayuan.parking.dao.ParkChannelDao;
import com.sxhuayuan.parking.entity.Agent;
import com.sxhuayuan.parking.entity.ParkChannel;
import com.sxhuayuan.parking.entity.ParkingLot;
import com.sxhuayuan.parking.entity.ParkingLotUser;
import com.sxhuayuan.parking.service.ParkChannelService;
import com.sxhuayuan.parking.service.ParkingLotService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service("parkChannelServiceImpl")
public class ParkChannelServiceImpl extends BaseServiceImpl<ParkChannel, Long> implements ParkChannelService {

	@Autowired
	ParkChannelDao dao;

	@Autowired
	ParkingLotService parkingLotService;

	@Autowired
	OrderDao orderDao;

	@Override
	public BaseDao<ParkChannel, Long> getDAO() {
		return dao;
	}

	@Override
	public ParkChannel findBySn(String sn) {
		return dao.findBySn(sn);
	}

	@Override
	public void save(ParkChannel entity) {
		entity.setSn(RandomStringUtils.randomNumeric(8));
		super.save(entity);
	}

	@Override
	@Transactional(readOnly = true)
	public Page<ParkChannel> findPage(Pageable pageable, ParkChannel.Type type, Agent agent) {
		StringBuilder sb = new StringBuilder("select p from ParkChannel p join AgentRelation r on p.agent=r.child where r.parent.id=").append(agent.getId());
		List<Filter> filters = pageable.getFilters();
		if (filters != null) {
			for (Filter filter : filters) {
				setCondition(sb, filter);
			}
		}

		sb.append(" order by p.id desc");
		return findPage(sb.toString(), sb.toString().replace("select p", "select count(p.id)"), pageable.getPageSize(), pageable.getPageNumber());
	}

	@Override
	public Long countByParkingLot(ParkingLotUser parkingLotUser, ParkChannel.Type type) {
		Set<ParkingLot> parkingLots = parkingLotUser.getParkingLots();
		if (parkingLots.size() <= 0) {
			return 0L;
		}
		List<Long> ids = new ArrayList<>();
		for (ParkingLot parkingLot : parkingLots) {
			ids.add(parkingLot.getId());
		}
		return dao.countByParkingLot(ids);
	}

	@Override
	@Transactional(readOnly = true)
	public Page<ParkChannel> findPageByParkingLotUser(Pageable pageable, ParkingLotUser parkingLotUser) {
		if (parkingLotUser == null || parkingLotUser.getParkingLots().size() <= 0) {
			return new Page<>();
		}
		StringBuilder sb = new StringBuilder("select p from ParkChannel p where ");
		Set<ParkingLot> parkingLots = parkingLotUser.getParkingLots();
		List<Long> ids = new ArrayList<>();
		for (ParkingLot parkingLot : parkingLots) {
			ids.add(parkingLot.getId());
		}
		if (ids.size() == 1) {
			sb.append(" p.parkingLot.id=").append(ids.get(0));
		} else {
			sb.append(" p.parkingLot.id in(").append(StringUtils.join(ids.toArray(), ',')).append(") ");
		}
		List<Filter> filters = pageable.getFilters();
		if (filters != null) {
			for (Filter filter : filters) {
				setCondition(sb, filter);
			}
		}

		sb.append(" order by p.id desc");
		return findPage(sb.toString(), sb.toString().replace("select p", "select count(p.id)"), pageable.getPageSize(), pageable.getPageNumber());
	}

	@Override
	public ParkChannel findByParkingLotAndTypeAndName(ParkingLot parkingLot, ParkChannel.Type type, String name) {
		return dao.findByParkingLotAndTypeAndName(parkingLot, type, name);
	}

	/** 组装查询条件 */
	private void setCondition(StringBuilder sb, Filter filter) {
		if (filter.getProperty() == null || "".equals(filter.getProperty()) || filter.getValue() == null || "".equals(filter.getValue())) {
			return;
		}
		switch (filter.getProperty()) {

		case "parkingName": {
			sb.append(" and p.parkingLot.name='").append(filter.getValue()).append("' ");
			break;
		}

		case "name": {
			sb.append(" and p.name='").append(filter.getValue()).append("' ");
			break;
		}

		case "istartTime": {
			sb.append(" and p.createDate>='").append(filter.getValue()).append("' ");
			break;
		}

		case "iendTime": {
			sb.append(" and p.createDate<='").append(filter.getValue()).append("' ");
			break;
		}

		case "deviceId": {
			sb.append(" and p.deviceId='").append(filter.getValue()).append("' ");
			break;
		}

		case "sn": {
			sb.append(" and p.sn='").append(filter.getValue()).append("' ");
			break;
		}

		case "type": {
			sb.append(" and p.type='").append(filter.getValue()).append("' ");
			break;
		}

		default:
		}

	}

	/** 删除车场某个出口 */
	@Override
	public void delete(Long id) {
		/** 将订单表中该车场出口设置为null */
		if (orderDao.findCountByExit(id) > 0) {
			orderDao.setExitIdNull(id);
		}
		dao.deleteById(id);
	}

	@Override
	public ParkChannel findByDevice(Long lotId, String deviceId) {
		return dao.findByDeviceId(lotId, deviceId);
	}

	@Override
	public ParkChannel findByChannelSn(Long lotId, String channelOutSn){
		return dao.findByChannelSn(lotId, channelOutSn);
	}

	@Override
	public List<ParkChannel> findByParkingLotIdAndType(Long lotId, ParkChannel.Type type){
		return dao.findByParkingLotIdAndType(lotId, type);
	}
}
